﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmartMathLibrary.Space.CoreTypes;

namespace SmartMathLibrary.Space.QueryEngine
{
    /// <summary>
    /// Defines a dimension option of a query.
    /// </summary>
    public enum DimensionOption
    {
        /// <summary>
        /// Only the number of rows interests in the query.
        /// </summary>
        OnlyRow = 0,

        /// <summary>
        /// Only the number of columns interests in the query.
        /// </summary>
        OnlyColumn = 1,

        /// <summary>
        /// The number of rows and columns interests in the query.
        /// </summary>
        RowAndColumn = 2
    }

    /// <summary>
    /// This class represents a dimension query for tables and matrices.
    /// </summary>
    [Serializable]
    public class DimensionQuery : AbstractSpaceQuery
    {
        /// <summary>
        /// The number of rows.
        /// </summary>
        private int rows;

        /// <summary>
        /// The number of columns.
        /// </summary>
        private int columns;

        /// <summary>
        /// Initializes a new instance of the <see cref="DimensionQuery"/> class.
        /// </summary>
        /// <param name="rows">The number of rows.</param>
        /// <param name="columns">The number of columns.</param>
        public DimensionQuery(int rows, int columns)
            : base()
        {
            this.rows = rows;
            this.columns = columns;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DimensionQuery"/> class.
        /// </summary>
        /// <param name="rows">The number of rows.</param>
        /// <param name="columns">The number of columns.</param>
        /// <param name="status">The object status criteria.</param>
        public DimensionQuery(int rows, int columns, SpaceObjectStatus status)
            : base(status)
        {
            this.rows = rows;
            this.columns = columns;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DimensionQuery"/> class.
        /// </summary>
        /// <param name="rows">The number of rows.</param>
        /// <param name="columns">The number of columns.</param>
        /// <param name="limit">The maximum number of query results.</param>
        public DimensionQuery(int rows, int columns, int limit)
            : base(limit)
        {
            this.rows = rows;
            this.columns = columns;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DimensionQuery"/> class.
        /// </summary>
        /// <param name="rows">The number of rows.</param>
        /// <param name="columns">The number of columns.</param>
        /// <param name="limit">The maximum number of query results.</param>
        /// <param name="status">The object status criteria.</param>
        public DimensionQuery(int rows, int columns, int limit, SpaceObjectStatus status)
            : base(limit, status)
        {
            this.rows = rows;
            this.columns = columns;
        }

        /// <summary>
        /// Gets or sets the number of rows.
        /// </summary>
        /// <value>The number of rows.</value>
        public int Rows
        {
            get { return this.rows; }
            set { this.rows = value; }
        }

        /// <summary>
        /// Gets or sets the number of columns.
        /// </summary>
        /// <value>The number of columns.</value>
        public int Columns
        {
            get { return this.columns; }
            set { this.columns = value; }
        }

        /// <summary>
        /// Defines the query criteria of the specified query.
        /// </summary>
        /// <param name="item">The query source items.</param>
        /// <returns>
        /// The space ID fulfills the query criteria the method returns true otherwise, false.
        /// </returns>
        public override bool QueryDefinition(ISpaceEntry item)
        {
            if ((item is SpaceMatrix) || (item is SpaceTable))
            {
                if (item is SpaceMatrix)
                {
                    SpaceMatrix check = (SpaceMatrix) item;

                    return ((check.Rows == this.rows) && (check.Columns == this.columns));
                }

                if (item is SpaceTable)
                {
                    SpaceTable check = (SpaceTable) item;

                    return ((check.Rows == this.rows) && (check.Columns == this.columns));
                }
            }

            return false;
        }
    }
}